package cn.turboinfo.dongying.api.domain.util;

import com.google.common.collect.Maps;

import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;

/**
 * 手机工具类
 *
 * @author qatang
 */
public class PhoneUtils {
    /*
     	         +---+      +------------+
             +---+ 3 +------+    0-9     +---+
             |   +---+      +------------+   |
             |                               |
             |   +---+      +------------+   |
             +---+ 4 +------+    4-9     +---+
             |   +---+      +------------+   |
             |                               |
             |   +---+      +------------+   |
             +---+ 5 +------+ 0-3 or 5-9 +---+
             |   +---+      +------------+   |
             |                               |
      +---+  |   +---+      +------------+   |  +-------+
      | 1 +------+ 6 +------+   6 or 7   +------+  0-9  |
      +---+  |   +---+      +------------+   |  +-------+
             |                               |    8位数字
             |   +---+      +------------+   |
             +---+ 7 +------+ 0,1 or 3-8 +---+
             |   +---+      +------------+   |
             |                               |
             |   +---+      +------------+   |
             +---+ 8 +------+    0-9     +---+
             |   +---+      +------------+   |
             |                               |
             |   +---+      +------------+   |
             +---+ 9 +------+    0-9     +---+
                 +---+      +------------+
     */

    /**
     * 手机号第1位
     */
    private static final String PHONE_FIRST_NUM = "1";

    /**
     * 手机号第2位可选范围
     */
    private static final String[] PHONE_SECOND_NUM_RANGE = {"3", "4", "5", "6", "7", "8", "9"};

    /**
     * 手机号第3位可选范围与第2位对应关系
     */
    private static final Map<String, String[]> PHONE_THIRD_NUM_RANGE_MAP = Maps.newHashMap();

    static {
        PHONE_THIRD_NUM_RANGE_MAP.put("3", new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}); // 0-9
        PHONE_THIRD_NUM_RANGE_MAP.put("4", new String[]{"4", "5", "6", "7", "8", "9"}); // 4-9
        PHONE_THIRD_NUM_RANGE_MAP.put("5", new String[]{"0", "1", "2", "3", "5", "6", "7", "8", "9"}); // 0-3 or 5-9
        PHONE_THIRD_NUM_RANGE_MAP.put("6", new String[]{"6", "7"}); // 6 or 7
        PHONE_THIRD_NUM_RANGE_MAP.put("7", new String[]{"0", "1", "3", "4", "5", "6", "7", "8"}); // 0,1 or 3-8
        PHONE_THIRD_NUM_RANGE_MAP.put("8", new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}); // 0-9
        PHONE_THIRD_NUM_RANGE_MAP.put("9", new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}); // 0-9
    }

    /**
     * 合法手机号格式正则表达式
     */
    private static final Pattern PATTERN_PHONE_NUM = Pattern.compile("^1(?:3\\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\\d|9\\d)\\d{8}$");

    /**
     * 4到6位短信验证码正则表达式
     */
    private static final Pattern PATTERN_SMS_CODE = Pattern.compile("^\\d{4,6}$");

    /**
     * 手机号格式是否合法
     *
     * @param phoneNum 手机号
     * @return 是否合法
     */
    public static boolean isValidPhoneNum(String phoneNum) {
        return Optional.ofNullable(phoneNum).isPresent() && PATTERN_PHONE_NUM.matcher(phoneNum).matches();
    }

    /**
     * 手机号打码
     *
     * @param phoneNum 手机号
     * @return 打码后的手机号
     */
    public static String maskPhoneNum(String phoneNum) {
        return maskPhoneNum(phoneNum, 3, 4);
    }

    /**
     * 手机号打码
     *
     * @param phoneNum 手机号
     * @return 打码后的手机号
     */
    public static String maskPhoneNum(String phoneNum, int leftRest, int rightRest) {
        return MaskUtils.maskPartialString(phoneNum, leftRest, rightRest, "*", 0);
    }

    /**
     * 短信验证码格式是否合法
     *
     * @param smsCode 短信验证码
     * @return 是否合法
     */
    public static boolean isValidSmsCode(String smsCode) {
        return Optional.ofNullable(smsCode).isPresent() && PATTERN_SMS_CODE.matcher(smsCode).matches();
    }

}
